home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_3.9 / THRESHO / THRESHO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  4.7 KB  |  182 lines

  1. /* 
  2.  * thresho.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* THRESHO:     program performs binarization by Otsu's discriminant method
  10.  *                    usage: thresho inimg outimg [-i] [-L]
  11.  *
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <images.h>
  17. #include <tiffimage.h>
  18. #include <math.h>
  19. #include <string.h>
  20. extern void print_sos_lic ();
  21.  
  22. #define NHIST 256               /* no. bins in histogram */
  23.  
  24. long usage (short);
  25. long input (int, char **, short *);
  26.  
  27. main (int argc, char *argv[])
  28. {
  29.   Image *imgI, *imgO;           /* I/O image structures */
  30.   unsigned char **imgIn, **imgOut;  /* input and output images */
  31.   long width, height;           /* image size */
  32.   long iHist[NHIST];            /* hist. of intensities */
  33.   double m0Low, m0High, m1Low, m1High, varLow, varHigh;
  34.   double prob[NHIST];
  35.   double varWithin, varWMin;
  36.   long thresh;
  37.   short invertFlag;             /* if =0, dark -> ON; if =1, dark -> OFF */
  38.   long nHistM1;
  39.   long x, y;                    /* image coordinates */
  40.   long i, j, n;
  41.  
  42.  
  43.   if (input (argc, argv, &invertFlag) < 0)
  44.     return (-1);
  45.  
  46. /* allocate input and output image memory */
  47.   imgI = ImageIn (argv[1]);
  48.   imgIn = ImageGetPtr (imgI);
  49.   height = ImageGetHeight (imgI);
  50.   width = ImageGetWidth (imgI);
  51.   imgO = ImageAlloc (height, width, 8);
  52.   imgOut = ImageGetPtr (imgO);
  53.  
  54. /* compile histogram */
  55.   printf ("MAIN: Compile histogram...\n");
  56.   for (i = 0; i < NHIST; i++)
  57.     iHist[i] = 0;
  58.   for (y = 0, n = 0; y < height; y++) {
  59.     for (x = 0; x < width; x++) {
  60.       iHist[imgIn[y][x]]++;
  61.       n++;
  62.     }
  63.   }
  64.  
  65. /* compute probabilities */
  66.   for (i = 0; i < NHIST; i++)
  67.     prob[i] = (double) iHist[i] / (double) n;
  68.  
  69. /* find best threshold by computing moments for all thresholds */
  70.   nHistM1 = NHIST - 1;
  71.   for (i = 1, thresh = 0, varWMin = 100000000.0; i < nHistM1; i++) {
  72.     m0Low = m0High = m1Low = m1High = varLow = varHigh = 0.0;
  73.     for (j = 0; j <= i; j++) {
  74.       m0Low += prob[j];
  75.       m1Low += j * prob[j];
  76.     }
  77.     m1Low = (m0Low != 0.0) ? m1Low / m0Low : i;
  78.     for (j = i + 1; j < NHIST; j++) {
  79.       m0High += prob[j];
  80.       m1High += j * prob[j];
  81.     }
  82.     m1High = (m0High != 0.0) ? m1High / m0High : i;
  83.     for (j = 0; j <= i; j++)
  84.       varLow += (j - m1Low) * (j - m1Low) * prob[j];
  85.     for (j = i + 1; j < NHIST; j++)
  86.       varHigh += (j - m1High) * (j - m1High) * prob[j];
  87.  
  88.     varWithin = m0Low * varLow + m0High * varHigh;
  89.     if (varWithin < varWMin) {
  90.       varWMin = varWithin;
  91.       thresh = i;
  92.     }
  93.   }
  94.  
  95. /*  printf ("Min variance is %5.2f at %d\n", varWMin, thresh); */
  96.   printf ("Calculated threshold value (by Otsu method) = %d\n", thresh);
  97.  
  98. /* output thresholded image */
  99.   if (invertFlag == 0) {
  100.     for (y = 0, n = 0; y < height; y++)
  101.       for (x = 0; x < width; x++)
  102.         imgOut[y][x] = (imgIn[y][x] > thresh) ? 255 : 0;
  103.   }
  104.   else {
  105.     for (y = 0, n = 0; y < height; y++)
  106.       for (x = 0; x < width; x++)
  107.         imgOut[y][x] = (imgIn[y][x] < thresh) ? 255 : 0;
  108.   }
  109.  
  110.   ImageOut (argv[2], imgO);
  111. }
  112.  
  113.  
  114.  
  115. /* USAGE:       function gives instructions on usage of program
  116.  *                    usage: usage (flag)
  117.  *              When flag is 1, the long message is given, 0 gives short.
  118.  */
  119.  
  120. long
  121. usage (flag)
  122.      short flag;                /* flag =1 for long message; =0 for short message */
  123. {
  124.  
  125. /* print short usage message or long */
  126.   printf ("USAGE: thresho inimg outimg [-i] [-L]\n");
  127.   if (flag == 0)
  128.     exit (1);
  129.  
  130.   printf ("\nthresho program performs binarization with respect to\n");
  131.   printf ("automatically determined intensity threshold;\n");
  132.   printf ("the input gray-level image is converted to a binary image;\n");
  133.   printf ("threshold determination is made by Otsu's\n");
  134.   printf ("moment preservation method.\n\n");
  135.   printf ("ARGUMENTS:\n");
  136.   printf ("    inimg: input image filename (TIF)\n");
  137.   printf ("   outimg: output image filename (TIF)\n\n");
  138.   printf ("OPTIONS:\n");
  139.   printf ("       -i: INVERT: intensities ABOVE (lighter) threshold set to 0\n");
  140.   printf ("           and those BELOW (darker) threshold set to 255\n");
  141.   printf ("       -L: print Software License for this module\n");
  142.  
  143.   return (-1);
  144. }
  145.  
  146.  
  147. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  148.  
  149. /* INPUT:       function reads input parameters
  150.  *                  usage: input (argc, argv)
  151.  */
  152.  
  153. long
  154. input (argc, argv, invertFlag)
  155.      int argc;
  156.      char *argv[];
  157.      short *invertFlag;         /* if =0, dark -> ON; if =1, dark -> OFF */
  158. {
  159.   long n;
  160.  
  161.   *invertFlag = 0;
  162.  
  163.   if (argc == 1)
  164.     USAGE_EXIT (1);
  165.   if (argc == 2)
  166.     USAGE_EXIT (0);
  167.  
  168.   for (n = 3; n < argc; n++) {
  169.     if (strcmp (argv[n], "-i") == 0) {
  170.       *invertFlag = 1;
  171.     }
  172.     else if (strcmp (argv[n], "-L") == 0) {
  173.       print_sos_lic ();
  174.       exit (0);
  175.     }
  176.     else
  177.       USAGE_EXIT (0);
  178.   }
  179.  
  180.   return (0);
  181. }
  182.